from typing import Generic, List, Optional, TypeVar

from pydantic import BaseModel, ConfigDict, Field

from app.enums.result_code import ResultCode

T = TypeVar("T")


class BaseSchema(BaseModel):
    model_config = ConfigDict(
        validate_by_name=True,  # 允许使用字段名验证
        from_attributes=True,  # 允许使用属性名验证
        use_enum_values=True,  # 允许使用枚举值验证
        extra="ignore",  # 忽略额外的字段
        populate_by_name=True,  # 允许使用字段名填充
    )


class Response(BaseModel, Generic[T]):
    """基础响应模型"""

    code: Optional[str] = Field(None, description="状态码")
    data: Optional[T] = Field(None, description="响应数据")
    msg: Optional[str] = Field(None, description="消息")

    def __init__(
        self,
        code: str = None,
        msg: Optional[str] = None,
        result_code: Optional[ResultCode] = None,
        data: Optional[T] = None,
    ):
        """
        初始化响应模型

        Args:
            code: 状态码
            data: 响应数据
            msg: 消息
        """
        _code = result_code.code if result_code else (code or ResultCode.SUCCESS.code)
        _msg = result_code.label if result_code else (msg or ResultCode.SUCCESS.label)
        super().__init__(code=_code, data=data, msg=_msg)

    def is_success(self) -> bool:
        """
        判断响应是否成功

        Returns:
            bool: 如果状态码为 "00000"，则返回 True；否则返回 False
        """
        return self.code == "00000"

    @classmethod
    def success(self, *, data: Optional[T] = None, msg: Optional[str] = None) -> "Response[T]":
        """
        成功响应

        Args:
            data: 响应数据
            msg: 消息

        Returns:
            Response[T]: 成功响应模型
        """
        return Response[T](code=ResultCode.SUCCESS.code, data=data, msg=msg or ResultCode.SUCCESS.label)

    @classmethod
    def failed(
        self,
        *,
        code: Optional[str] = None,
        msg: Optional[str] = None,
        data: Optional[T] = None,
        result_code: Optional[ResultCode] = None,
    ) -> "Response[T]":
        """
        失败响应

        Args:
            code: 状态码
            msg: 消息
            data: 响应数据
            result_code: 结果码

        Returns:
            GceResponse[T]: 失败响应模型
        """
        _code = result_code.code if result_code else (code or ResultCode.SYSTEM_ERROR.code)
        _msg = result_code.label if result_code else (msg or ResultCode.SYSTEM_ERROR.label)
        return Response[T](code=_code, msg=_msg, data=data)


class Pagination(BaseModel, Generic[T]):
    """分页响应模型"""

    page: int = Field(1, description="当前页码")
    size: int = Field(100, description="每页记录数")
    total: Optional[int] = Field(None, description="总记录数")
    list: Optional[List[T]] = Field(None, description="数据项列表")
